<template>
  <div class="app-container">
    <el-row :gutter="20" class="full-height clear-margin">
 
      <!--图书-->
      <el-col :span="24" :xs="24" class="clear-padding">
        <div class="head-container flex-center" style="border-bottom: 1px solid #ddd;">
          <div>
            <el-breadcrumb separator-class="el-icon-arrow-right">
              <el-breadcrumb-item>书籍管理</el-breadcrumb-item>
            </el-breadcrumb>
          </div>
          <div style="text-align: right">
            <el-button type="primary"
                       plain
                       size="small"
                       v-has-permi="['library:book:insert']"
                       @click="handleAdd">添加书籍</el-button>
            <el-button type="danger"
                       plain
                       v-has-permi="['library:book:delete']"
                       :disabled="multiple"
                       size="small"
                       @click="handleDelete">删除书籍</el-button>
          </div>
        </div>

        <div class="body-container">
          <el-form :model="queryParams"
                   ref="queryForm"
                   class="queryForm"
                   :inline="true">
            <el-form-item label="搜索框：" prop="keywords">
              <el-input v-model="queryParams.keywords"
                        placeholder="请输入关键字"
                        clearable
                        size="small"
                        @input="handleQuery" />
            </el-form-item>
          </el-form>

          <el-table v-loading="loading"
                    :data="bookList"
                    @selection-change="handleSelectionChange">
            <el-table-column type="selection"
                             width="30"
                             align="center" />
            <el-table-column label="书号"
                             align="center"
                             key="isbn"
                             prop="isbn" 
                             width="130" />
            <el-table-column label="书名"
                             align="center"
                             key="title"
                             prop="title"
                             width="260" 
                             :show-overflow-tooltip="true" />
            <el-table-column label="分类"
                             align="center"
                             key="classifi"
                             prop="classification.cname"
                             width="80" 
                             :show-overflow-tooltip="true" />
            <el-table-column label="作者"
                             align="center"
                             key="author"
                             prop="author"
                             width="220" 
                             :show-overflow-tooltip="true" />
            <el-table-column label="出版社"
                             align="center"
                             key="press"
                             prop="press"
                             width="140" />
            <el-table-column label="状态"
                             align="center"
                             width="60" 
                             prop="status"
                             :formatter="formatter"/>

            <el-table-column label="操作">
              <template slot-scope="scope">
                <el-button size="small"
                           type="primary"
                           plain
                           icon="el-icon-edit"
                           v-has-permi="['library:book:detail']"
                           @click="handleDetail(scope.row)">详细
                </el-button>
                <el-button size="small"
                           type="primary"
                           plain
                           icon="el-icon-edit"
                           v-has-permi="['library:book:update']"
                           @click="handleUpdate(scope.row)">编辑
                </el-button>
                <el-button size="small"
                           type="danger"
                           plain
                           icon="el-icon-delete"
                           v-has-permi="['library:book:delete']"
                           @click="handleDelete(scope.row)">删除
                </el-button>
              </template>
            </el-table-column>
          </el-table>

          <pagination
            v-show="total>0"
            :total="total"
            :page.sync="queryParams.pageNum"
            :limit.sync="queryParams.pageSize"
            @pagination="getList"
          />
        </div>

      </el-col>
    </el-row>

    <!-- 添加或修改参数配置对话框 -->
    <el-dialog :title="title"
               :visible.sync="open"
               width="90%"
               top="20vh"
               :close-on-click-modal="false"
               append-to-body>
      <el-form ref="form"
               :model="form"
               :rules="rules"
               label-width="100px">
        <el-row>
          <el-col :span="12">
            <el-form-item label="书号：" >
              <el-input v-model="form.isbn"
                        :disabled="form._id !== undefined"
                        placeholder="请输入书号"
                        @input="handleInfoQuery"
                        maxlength="30"/>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="书名：" >
              <el-input v-model="form.title"
                        :disabled=!isedit
                        placeholder="请输入书名"
                        maxlength="30"/>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="12">
            <el-form-item label="分类：" >
              <el-select v-model="form.cname" placeholder="请选择分类">
                <el-option
                   v-for=" item in classOptions"
                          :key="item.id"
                          :lable="item.name"
                          :value="item.name">
                  </el-option>
              </el-select>
                         
            </el-form-item>
          </el-col>
          
          <el-col :span="12">
            <el-form-item label="豆瓣评分：" >
              <el-input v-model="form.douban_rate"
                        placeholder="请输入豆瓣评分"
                        maxlength="50"/>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="12">
            <el-form-item label="作者：" >
              <el-input v-model="form.author"
                        placeholder="请输入作者"
                        maxlength="30"/>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="出版社：" >
              <el-input v-model="form.press"
                        placeholder="请输入出版社"
                        maxlength="30"/>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="12">
            <el-form-item label="译者：" >
              <el-input v-model="form.translater"
                        placeholder="请输入译者"
                        maxlength="30"/>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="价格：" >
              <el-input v-model="form.price"
                        placeholder="请输入价格"
                        maxlength="30"/>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="12">
            <el-form-item label="页数：" >
              <el-input v-model="form.pages"
                        placeholder="请输入页数"
                        maxlength="30"/>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="字数：" >
              <el-input v-model="form.sizes"
                        placeholder="请输入字数"
                        maxlength="30"/>
            </el-form-item>
          </el-col>
        </el-row>

        <el-row>
   
          <el-col :span="24">
            <el-form-item label="简介：" >
       
                <el-input v-model="form.summary"
                        type="textarea"
                        :rows=10
                        placeholder="请输入书籍简介" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="12">
            <el-form-item label="封面地址：" >
       
                <el-input v-model="form.image"
                        placeholder="请输入封面url" 
                        maxlength="100"/>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="状态："  >
              <el-radio-group v-model="form.status" >
                <el-radio
                  v-for="dict in statusOptions"
                  :key="dict.dictValue"
                  :label="dict.dictValue">
                  {{dict.dictLabel}}
                </el-radio>
              </el-radio-group>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="12">
            <el-form-item label="电子版：">
                
              <!-- el-input v-model="{{ form.url }}"
                        :disabled=true
                        :visable=true
                        placeholder="电子版地址"/ --> 
              <el-button  :disabled="isaval"  type="success" @click="handleDownload" plain>下载</el-button>   
              {{ form.url }}  
            </el-form-item>
            <el-form-item>               
                 <el-button   type="success" @click="handleSearch" plain>外部搜索电子版</el-button>   
              </el-form-item>
          </el-col>

          

          
        </el-row>
        <el-row>
          <el-col :span="24">
            <el-form-item >
            <el-upload
                    ref="upload"
                    action=""
                    :on-remove="handleRemove"
                    :on-change="handleFileChange"
                    :file-list="uploadFileList"
                    :show-file-list="false"
                    :limit="1"
                    :multiple="false"
                    :auto-upload="false">
                    <el-button slot="trigger" type="primary" plain>选择文件</el-button>
                    <el-button style="margin-left: 10px;"  type="success" @click="handleUpload" plain>上传</el-button>
                    <el-button type="danger" @click="clearFileHandler" plain>清空</el-button>
              </el-upload>
              <el-collapse>

              <el-collapse-item v-for="(item, index) in uploadFileList" :key="index">
                <template slot="title">
                  <div class="upload-file-item">
                    <div class="file-info-item file-name">文件名：{{ item.name }}</div>
                    <div class="file-info-item file-size">文件大小：{{ item.size | transformByte }} </div>
                    <div class="file-info-item file-progress">
                      <span class="file-progress-label">文件进度：</span>
                      <el-progress :percentage="item.uploadProgress" class="file-progress-value" />
                    </div>
                    <div class="file-info-item file-size"><span>状态：</span>
                      <el-tag v-if="item.status === '等待上传'" size="medium" type="info">等待上传</el-tag>
                      <el-tag v-else-if="item.status === '校验MD5'" size="medium" type="warning">校验MD5</el-tag>
                      <el-tag v-else-if="item.status === '正在上传'" size="medium">正在上传</el-tag>
                      <el-tag v-else-if="item.status === '上传成功'" size="medium" type="success">上传完成</el-tag>
                      <el-tag v-else size="medium" type="danger">上传错误</el-tag>
                    </div>
                  </div>
                </template>
            
            
            <div class="file-chunk-list-wrapper">     
            <!-- 分片列表 -->
            <el-table
              :data="item.chunkList"
              max-height="400"
              style="width: 100%">
              <el-table-column
              prop="chunkNumber"
              label="分片序号"
              width="180">
              </el-table-column>
              <el-table-column
              prop="progress"
              label="上传进度">
              <template v-slot="{ row }">
                <el-progress v-if="!row.status || row.progressStatus === 'normal'" :percentage="row.progress" />
                <el-progress v-else :percentage="row.progress" :status="row.progressStatus" :text-inside="true" :stroke-width="16" />
              </template>
              </el-table-column>
              <el-table-column
                prop="status"
                label="状态"
                width="180">
                </el-table-column>
               </el-table>
             </div>
              </el-collapse-item>
            </el-collapse>   
            </el-form-item>
          </el-col>   
          
          

        </el-row>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" @click="submitForm">确 定</el-button>
        <el-button @click="cancel">取 消</el-button>
      </div>
    </el-dialog>

     <!-- zlibrary搜索及下载对话框 -->
     <el-dialog :title="ztitle"
               :visible.sync="zopen"
               width="90%"
               top="20vh"
               :close-on-click-modal="false"
               append-to-body>
      <el-form ref="zform"
               :model="zform"
               :rules="zrules"
               label-width="100px">
        <el-row>
          <el-col :span="12">
            <el-form-item label="书名：" >
              <el-input v-model="zform.title"
                        placeholder="书名"
                        @input="handleLibQuery"
                        maxlength="30"/>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="作者：" >
              <el-input v-model="zform.author"
                        placeholder="作者"
                        maxlength="30"/>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="12">
            <el-form-item label="出版社：" >
              <el-input v-model="zform.publisher"
                        placeholder="出版社"
                        maxlength="50"/>
            </el-form-item>

          </el-col>
          
          <el-col :span="12">
            <el-form-item label="扩展名：" >
              <el-input v-model="zform.extension"
                        placeholder="扩展名"
                        maxlength="50"/>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="12">
            <el-form-item label="语言：" >
              <el-input v-model="zform.language"
                        placeholder="语言"
                        maxlength="30"/>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="ISBN：" >
              <el-input v-model="zform.isbn"
                        placeholder="ISBN"
                        maxlength="30"/>
            </el-form-item>
          </el-col>
        </el-row>
 
 
        
      </el-form>
      <!-- div slot="footer" class="dialog-footer">
        <el-button type="primary" @click="zsubmitForm">确 定</el-button>
        <el-button @click="cancel">取 消</el-button>
      </div -->

      <el-table v-loading="loading"
                    :data="bookLibList">
                    <!-- @selection-change="handleSelectionChange"
                     el-table-column type="selection"
                             width="30"
                             align="center" / -->
            <el-table-column label="书名"
                             align="center"
                             key="title"
                             prop="title" 
                             width="260" 
                             :show-overflow-tooltip="true"/>
            <el-table-column label="作者"
                             align="center"
                             key="author"
                             prop="author"
                             width="180" 
                             :show-overflow-tooltip="true"/>
            <el-table-column label="出版社"
                             align="center"
                             key="publisher"
                             prop="publisher"
                             width="120" 
                             :show-overflow-tooltip="true"/>
            <el-table-column label="扩展名"
                             align="center"
                             key="extension"
                             prop="extension"
                             width="100" />
            <el-table-column label="文件大小"
                             align="center"
                             key="filesize"
                             prop="filesize"
                             :formatter="formatData"
                             width="100" />
            <el-table-column label="语言"
                             align="center"
                             key="language"
                             prop="language"
                             width="100" />
            <el-table-column label="年份"
                             align="center"
                             key="year"
                             prop="year"
                             width="100" />
            <el-table-column label="页数"
                             align="center"
                             key="pages"
                             prop="pages"
                             width="100" />

            <el-table-column label="操作">
              <template slot-scope="scope">

                <el-button size="small"
                           type="primary"
                           plain
                           icon="el-icon-edit"
                           @click="handleDownloadFromLib(scope.row)">下载
                </el-button>

              </template>
            </el-table-column>
          </el-table>

          <!--pagination
            v-show="libtotal>0"
            :total="libtotal"
            :page.sync="queryLibParams.pageNum"
            :limit.sync="queryLibParams.pageSize"
            @pagination="getLibList"
          / -->
      
    </el-dialog>


  </div>
</template>

<script>

import {listBooks, listClass, getBook, updateBook, addBook, delBook,getLibBooks, getBookInfo} from "@/api/library/books"
import {checkFileUploadedByMd5, getFileUploadUrls, mergeFile}  from "@/api/system/upload"
import Treeselect from "@riophae/vue-treeselect"
import { descriptionDictDataStatus } from "@/utils/global";


const FileStatus = {
  wait: '等待上传',
  getMd5: '校验MD5',
  uploading: '正在上传',
  success: '上传成功',
  error: '上传错误'
}
const chunkSize = 10 * 1024 * 1024
let currentFileIndex = 0
const FILE_UPLOAD_ID_KEY = 'file_upload_id'
import SparkMD5 from 'spark-md5'
import axios from 'axios'
import { title } from "process";

export default {
  
  name: "Books",
  data() {
    return {
      // 遮罩层
      loading: true,
      // 总条数
      total: 0,
      libtotal: 0,
      ids: [],
      multiple: true,
        // 总条数
      // 表格数据
      bookList: [],
      bookLibList: [],
      form: {},
      zform: {},
      classOptions: undefined,
      // 是否显示弹出层
      open: false,
      isedit: true,
      zopen: false,
      isaval : true,
      // 弹出层标题
      title: "",
      ztitle: "",
      // 表单校验
      rules: {
        isbn: [
            {required: true, message: "书号不能为空", trigger: "blur"},
            {min: 8, max: 13, message: '书号长度必须介于 8 和 13 之间', trigger: 'blur'}
          ],
         title: [
            {required: true, message: "书名不能为空", trigger: "blur"}
          ],
          cname: [
            {required: true, message: "分类不能为空", trigger: "blur"},
          ],
          author: [
            {required: true, message: "作者不能为空", trigger: "blur"},
          ],
          press: [
            {required: true, message: "出版社不能为空", trigger: "blur"},
          ],
          status: [
            {required: true, message: "出版社不能为空", trigger: "blur"},

          ]
      },
      zrules: {

         title: [
            {required: true, message: "书名不能为空", trigger: "blur"}
          ]          
      },
      defaultProps: {
        children: "pid",
        label: "name"
      },
      // 查询参数
      queryParams: {
        pageNum: 1,
        pageSize: 10,
        sort: "_id",
        keywords: undefined,
        status: true,
      },

      queryLibParams: {
        pageNum: 1,
        pageSize: 15,
        title: undefined,
  
      },
      queryBookInfoParams: {
        isbn: undefined,
      },

      statusOptions: [],
      changeDisabled: false,
      uploadDisabled: false,
        // 上传并发数
      simultaneousUploads: 3,
      uploadIdInfo: null,
      uploadFileList: [],
      retryList: []
    }
  },
  watch: {
    // 根据名称筛选部门树
    /* name(val) {
      this.$refs.tree.filter(val)
    } */
  },
  created() {
    this.getList()

    this.getclassOptions()
    this.getDicts("book_status").then(response => {
        this.statusOptions = response.data;
        //console.log(this.statusOptions)
    })

  },
  methods: {
    /** 查询图书列表 */
    getList() {
      this.loading = true
      listBooks(this.queryParams).then(response => {
            //console.log(response)
            
            if (response.data)
            {
              this.bookList = response.data.books
              this.total = response.data.total
            }
            this.loading = false
          }
        )
    },
     /** 书籍搜索结果列表 */
     getLibList(iszform) {
      this.loading = true
      if(iszform){
          this.queryLibParams.title = this.zform.title
      } else {
          this.queryLibParams.title = this.form.title
      }
      
      getLibBooks(this.queryLibParams).then(response => {
            this.bookLibList = response.data.books
            this.libtotal = response.data.total
            this.loading = false
          }
        )
    },
    getclassOptions()
    {
          listClass().then(response => {
            this.classOptions = response.data
          })
    },

    /** 转换部门数据结构 */
    formatter(row, index) {
    if (row.status == true) {
       row.status = "true"
    }
    if(row.status == false) {
       row.status = "false"
    }
      //console.log("row",row,descriptionDictDataStatus(row.status, this.statusOptions))
      return descriptionDictDataStatus(row.status, this.statusOptions)
    },
    /** 转换bool类型 */
    formatterbool(row, index) {
      if (row.status == true) {
          row.status = "true"
      }
      if(row.status == false) {
          row.status = "false"
      }   
      return row.status
      
    },

    normalizer(node) {
      if (node.children && !node.children.length) {
        delete node.children
      }
      return {
        id: node._id,
        label: '[' + node.id + '] ' + node.name,
        children: node.children
      }
    },
    // 筛选节点
    filterNode(value, data) {
      if (!value) return true
      return data.label.indexOf(value) !== -1
    },
    /** 搜索按钮操作 */
    handleQuery() {
        this.queryParams.pageNum = 1
        this.getList()
    },

    handleLibQuery() {
        this.queryParams.title = this.zform.title
        let iszform = true
        this.getLibList(iszform)
    },
    handleInfoQuery() {
      
        if (this.form._id == undefined && this.form.isbn != "" )
        {
            console.log("handle query bookinfo",this.form._id,this.form.isbn )
            this.queryBookInfoParams.isbn = this.form.isbn
            this.loading = true
            getBookInfo(this.queryBookInfoParams).then(response => {
                console.log(response.data)
                if (response.data.code == 200){
                  this.form.title = response.data.book.title
                this.form.author = response.data.book.author
                this.form.press = response.data.book.press
                this.form.douban_rate = response.data.book.rate
                this.form.summary = response.data.book.summary
                this.form.image = response.data.book.image
                this.form.pages = response.data.book.pages
                this.form.price = response.data.book.price
                this.form.press_date = response.data.book.pressDate
                this.form.translater = response.data.book.translator.toString()
                }
                
                this.loading = false
                if (response.data.code == 404) {
                  this.msgSuccess("数据库中无此书信息")
                }
            })
        }
        
        
    },

    /** 新增按钮操作 */
    handleAdd() {
        this.reset()
        this.open = true
        this.isedit = true
        this.title = "添加书籍"

    },
     /** 修改按钮操作 */
     handleUpdate(row) {
        this.reset()
        console.log(row)
        getBook(row._id).then(response => {
          console.log(response)
          let str_status= "false"
          if (response.data.book.status)  str_status= "true"

          this.form = { 
            _id: response.data.book._id,
            isbn: response.data.book.isbn,
            title: response.data.book.title,
            classifi: response.data.book.classification._id,
            cname: response.data.book.classification.cname,
            douban_rate: response.data.book.douban_rate,
            author: response.data.book.author,
            press: response.data.book.press,
            summary: response.data.book.summary,
            status: str_status,
            pages: response.data.book.pages,
            price: response.data.book.price,
            press_date : response.data.book.press_date,
            sizes : response.data.book.sizes,
            translater: response.data.book.translater,
            image: response.data.book.image,
            url: response.data.book.url
          } 
          if (response.data.book.url)  this.isaval = false
          this.open = true
          this.isedit = true
          this.title = "修改书籍"
        })
      },
      
      handleDetail(row) {
        this.reset()
        console.log(row)
        getBook(row._id).then(response => {
          console.log(response)
          let str_status= "false"
          if (response.data.book.status)  str_status= "true"

          this.form = { 
            _id: response.data.book._id,
            isbn: response.data.book.isbn,
            title: response.data.book.title,
            classifi: response.data.book.classification._id,
            cname: response.data.book.classification.cname,
            douban_rate: response.data.book.douban_rate,
            author: response.data.book.author,
            press: response.data.book.press,
            summary: response.data.book.summary,
            status: str_status,
            pages: response.data.book.pages,
            price: response.data.book.price,
            press_date : response.data.book.press_date,
            sizes : response.data.book.sizes,
            translater: response.data.book.translater,
            image: response.data.book.image,
            url: response.data.book.url
          } 
          if (response.data.book.url)  this.isaval = false
          this.open = true
          this.isedit = false
          this.title = "书籍详细信息"
        })
      },


      handleDelete(row) {
        const bookIds = row._id ? [{"id":row._id,"title":row.title}] : this.ids
        const names = bookIds.map(item => item.title)
        this.$confirm('是否确认删除书籍为"' + names + '"?', "警告", {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning"
        }).then(function () {
          //console.log('book:',bookIds)
          bookIds.forEach(function(item) {
              console.log("del:",item.id)
              delBook(item.id).then(response => {
                if (response.data.code == 200){
                    console.log("del:",item.id,"成功")
                } else {
                  console.log("del:",item.id,"失败")
                }
                
              }) 
          })

        }).then(() => {
          this.getList()
          this.msgSuccess("删除成功")
        }).catch(() => {
        }) 
      },
    /** 提交按钮 */
    submitForm() {
      //this.open = false
      //this.form.status = this.form.status === '是' ? 1 : 2
      this.clearFileHandler()
      this.$refs["form"].validate(valid => {
          if (valid) {
            if (this.form._id != undefined ) {
              if (this.isedit) {
                console.log("update:",this.form)
                updateBook(this.form).then(response => {
                this.msgSuccess("修改成功")
                this.open = false
                this.getList()
              })
              } else {
                this.open = false
              }
               
            } else {
               console.log("add",this.form)
               addBook(this.form).then(response => {
                this.msgSuccess("添加成功")
                this.open = false
                this.getList()
              })
            }
          }
        })
    },
    // 取消按钮
    cancel() {
        this.open = false
        this.reset()
        this.clearFileHandler()
      },
    // 表单重置
    reset() {
      this.form = {
          _id: undefined,
          isbn: undefined,
          title: undefined,
          classifi: undefined,
          cname: undefined,
          douban_rate: undefined,
          author: undefined,
          press: undefined,
          summary: undefined,
          pages: undefined,
          price: undefined,
          press_date : undefined,
          sizes : undefined,
          translater: undefined,
          status: "true",
          url: undefined
      }
      this.resetForm("form")
    },
    handleUpload() {
      console.log('handleUpload....' )
      const self = this
      const files = this.uploadFileList
      if (files.length === 0) {
        this.msgSuccess('请先选择文件')
        return
      }
      // 当前操作文件
      const currentFile = files[currentFileIndex]
      currentFile.status = FileStatus.getMd5
      // 1. 计算MD5
      this.getFileMd5(currentFile.raw, async (md5) => {
          // 2. 检查是否已上传
          console.log('1 文件MD5：' + md5)
          let para = {md5: md5}
          const checkResult = await checkFileUploadedByMd5(para)
          //console.log(checkResult)
          // 已上传
          if (checkResult.code == 200 & checkResult.data.status == 1 )  {
            this.msgSuccess(`上传成功，文件地址：${checkResult.data.uploadUrls}`)
            console.log('文件访问地址：' + checkResult.data.uploadUrls)
            currentFile.status = FileStatus.success
            currentFile.uploadProgress = 100
            this.form.url = checkResult.data.uploadUrls
            return
          } else if (checkResult.code == 200  && checkResult.data.status === 2) {  // "上传中" 状态
            // 获取已上传分片列表
            let chunkUploadedList = checkResult.data.chunkUploadedList
            currentFile.chunkUploadedList = chunkUploadedList  
          } else {   // 未上传
            console.log('未上传')
          }
          console.log('文件MD5：' + md5)
          // 3. 正在创建分片
          let fileChunks = self.createFileChunk(currentFile.raw, chunkSize)
          
          let param = {
            fileName: currentFile.name,
            fileSize: currentFile.size,
            chunkSize: chunkSize,
            fileMd5: md5,
            contentType: 'application/octet-stream'
          }
          // 4. 获取上传url
          let uploadIdInfoResult = await getFileUploadUrls(param)
          console.log('url:',uploadIdInfoResult)
          self.uploadIdInfo = uploadIdInfoResult.data
          self.saveFileUploadId(uploadIdInfoResult.data)
          let uploadUrls = uploadIdInfoResult.data.uploadUrls
          if (fileChunks.length !== uploadUrls.length) {
            console.log(uploadUrls)
            this.msgSuccess('文件分片上传地址获取错误')
            return
          }
          self.$set(currentFile, 'chunkList', [])
          fileChunks.map((chunkItem, index) => {
            currentFile.chunkList.push({
              chunkNumber: index + 1,
              chunk: chunkItem,
              uploadUrl: uploadUrls[index],
              progress: 0,
              status: '—'
            })
          })
          let tempFileChunks = []
          currentFile.chunkList.forEach((item) => {
            tempFileChunks.push(item)
          })
          currentFile.status = FileStatus.uploading
          // 处理分片列表，删除已上传的分片
          tempFileChunks = self.processUploadChunkList(tempFileChunks)
          // 5. 上传
          await self.uploadChunkBase(tempFileChunks)
          console.log('上传完成')
          
          // 6. 合并文件
           
          const mergeResult = await mergeFile({
            uploadId: self.uploadIdInfo.uploadId,
            fileName: currentFile.name,
            md5: md5
          }) 
          console.log('merg:',mergeResult)
          if (!mergeResult.success) {
            currentFile.status = FileStatus.error
            this.msgSuccess(mergeResult.error)
          } else {
            currentFile.status = FileStatus.success
            console.log('文件访问地址：' + mergeResult.data.url)
            this.form.url =  mergeResult.data.url
            this.msgSuccess(`上传成功，文件地址：${mergeResult.data.url}`)
          }
        }) 
    },
    clearFileHandler() {
        this.uploadFileList = []
        this.uploadIdInfo = null
    },

    handleFileChange(file, fileList) {
        this.uploadFileList = fileList
        this.uploadFileList.forEach((item) => {
          // 初始化自定义属性
          this.initFileProperties(item)
        })
    },

    initFileProperties(file) {
        file.chunkList = []
        file.status = FileStatus.wait
        file.progressStatus = 'warning'
        file.uploadProgress = 0
    },
    handleRemove(file, fileList) {
        this.uploadFileList = fileList
    },
    handleDownload () {
          
    },
    handleDownloadFromLib (row) {
      //console.log(row)
      let fileurl = "https://gateway.pinata.cloud/ipfs/"+row.ipfs_cid
      let filename = row.title+"."+row.extension
       // 将中文字符编码为URL编码格式
      const encodedFileName = encodeURIComponent(filename);
      //console.log(fileurl,encodedFileName)
      // 创建链接并模拟点击下载
      const link = document.createElement('a');
      link.href = fileurl;
      link.setAttribute('download', encodedFileName);
      link.style.display = 'none'; 
      document.body.appendChild(link);
      link.click();
      document.body.removeChild(link);
          
    },
    handleSearch(){
      console.log(this.form.title)
      this.zform = { 
          title : this.form.title,
          isbn : undefined,
          language : undefined,
          extension : undefined,
          publisher : undefined,
          author : undefined,
          filesize: undefined,
          year: undefined,
          pages: undefined
      }
      let iszform = false
      this.getLibList(iszform)  
      this.ztitle = "书籍搜索"
      this.open = false
      this.zopen = true
    },
    /**
       * 分片读取文件 MD5
       */
    getFileMd5(file, callback) {
        console.log('bgein md5')
        const blobSlice = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice
        const fileReader = new FileReader()
        // 计算分片数
        const totalChunks = Math.ceil(file.size / chunkSize)
        console.log('总分片数：' + totalChunks)
        let currentChunk = 0
        const spark = new SparkMD5.ArrayBuffer()
        loadNext()
        fileReader.onload = function (e) {
          try {
            spark.append(e.target.result)
          } catch (error) {
            console.log('获取Md5错误：' + currentChunk)
          }
          if (currentChunk < totalChunks) {
            currentChunk++
            loadNext()
          } else {
            callback(spark.end())
          }
        }
        fileReader.onerror = function () {
          console.warn('读取Md5失败，文件读取错误')
        }
        function loadNext () {
          const start = currentChunk * chunkSize
          const end = ((start + chunkSize) >= file.size) ? file.size : start + chunkSize
          // 注意这里的 fileRaw
          fileReader.readAsArrayBuffer(blobSlice.call(file, start, end))
        }
    },

    /**
       * 文件分片
       */
    createFileChunk(file, size = chunkSize) {
        const fileChunkList = []
        let count = 0
        while(count < file.size) {
          fileChunkList.push({
            file: file.slice(count, count + size),
          })
          count += size
        }
        return fileChunkList
    },

    /**
       * 处理即将上传的分片列表，判断是否有已上传的分片，有则从列表中删除
    */
    processUploadChunkList(chunkList) {
        const currentFile = this.uploadFileList[currentFileIndex]
        let chunkUploadedList = currentFile.chunkUploadedList
        if (chunkUploadedList === undefined || chunkUploadedList === null || chunkUploadedList.length === 0) {
          return chunkList
        }
        // 
        for (let i = chunkList.length - 1; i >= 0; i--) {
          const chunkItem = chunkList[i]
          for (let j = 0; j < chunkUploadedList.length; j++) {
            if (chunkItem.chunkNumber === chunkUploadedList[j]) {
              chunkList.splice(i, 1)
              break
            }
          }
        }
        return chunkList
    },

    uploadChunkBase(chunkList) {
        const self = this
        let successCount = 0
        let totalChunks = chunkList.length
        return new Promise((resolve, reject) => {
          const handler = () => {
            if (chunkList.length) {
              const chunkItem = chunkList.shift()
              // 直接上传二进制，不需要构造 FormData，否则上传后文件损坏
              axios.put(chunkItem.uploadUrl, chunkItem.chunk.file, {
                // 上传进度处理
                onUploadProgress: self.checkChunkUploadProgress(chunkItem),
                headers: {
                  'Content-Type': 'application/octet-stream'
                }
              }).then(response => {
                if (response.status === 200) {
                  console.log('分片：' + chunkItem.chunkNumber + ' 上传成功')
                  successCount++
                  // 继续上传下一个分片
                  handler()
                } else {
                  console.log('上传失败：' + response.status + '，' + response.statusText)
                }
              }).catch(error => {
                // 更新状态
                console.log('分片：' + chunkItem.chunkNumber + ' 上传失败，' + error)
                // 重新添加到队列中
                chunkList.push(chunkItem)
                handler()
              })
            }
            if (successCount >= totalChunks) {
              resolve()
            }
          }
          // 并发
          for (let i = 0; i < this.simultaneousUploads; i++) {
            handler()
          }
        })
    },

    /* getFileUploadUrls(fileParam) {
        let url = `http://127.0.0.1:8027/upload?_=${Math.random()}`
        return axios.post(url, fileParam)
    }, */

    saveFileUploadId(data) {
        localStorage.setItem(FILE_UPLOAD_ID_KEY, data)
    },

    /* checkFileUploadedByMd5(md5) {
        let url = `http://127.0.0.1:8027/upload/check?md5=${md5}`
        return new Promise((resolve, reject) => {
          axios.get(url).then((response) => {
            resolve(response.data)
          }).catch(error => {
            reject(error)
          })
        })
    }, */

    /* mergeFiles(file) {
        //const self = this
        
        let url = `http://127.0.0.1:8027/upload/merge?uploadId=${file.uploadId}&fileName=${file.fileName}&md5=${file.md5}`
        return new Promise((resolve, reject) => {
          axios.post(url).then(response => {
            let data = response.data
            if (!data.success) {
              file.status = FileStatus.error
              resolve(data)
            } else {
              file.status = FileStatus.success
              resolve(data)
            }
          }).catch(error => {
            this.msgSuccess('合并文件失败：' + error)
            file.status = FileStatus.error
            reject()
          })
        })
    }, */

    checkChunkUploadProgress(item) {
        return p => {
          item.progress = parseInt(String((p.loaded / p.total) * 100))
          this.updateChunkUploadStatus(item)
        }
    },

    updateChunkUploadStatus(item) {
        let status = FileStatus.uploading
        let progressStatus = 'normal'
        if (item.progress >= 100) {
          status = FileStatus.success
          progressStatus = 'success'
        }
        let chunkIndex = item.chunkNumber - 1
        let currentChunk = this.uploadFileList[currentFileIndex].chunkList[chunkIndex]
        // 修改状态
        currentChunk.status = status
        currentChunk.progressStatus = progressStatus
        // 更新状态
        this.$set(this.uploadFileList[currentFileIndex].chunkList, chunkIndex, currentChunk)
        // 获取文件上传进度
        this.getCurrentFileProgress()
    },

    getCurrentFileProgress() {
        const currentFile = this.uploadFileList[currentFileIndex]
        if (!currentFile || !currentFile.chunkList) {
          return
        }
        const chunkList = currentFile.chunkList
        const uploadedSize = chunkList.map((item) => item.chunk.file.size * item.progress).reduce((acc, cur) => acc + cur)
        // 计算方式：已上传大小 / 文件总大小
        let progress = parseInt((uploadedSize / currentFile.size).toFixed(2))
        currentFile.uploadProgress = progress
        this.$set(this.uploadFileList, currentFileIndex, currentFile)
      
    },

    handleSelectionChange(selection) {
      this.ids = selection.map(function (item) {  return {'id':item._id,'title': item.title}   })
      this.multiple = !selection.length 

    },

    formatData(row,column,cellValue) {
     
      var size = row.filesize;  
      if (!size) 
          return '0B'
        
      const unitSize = 1024
      if (size < unitSize) 
          return size + ' B'
        
        // KB
      if (size < Math.pow(unitSize, 2)) 
          return (size / unitSize).toFixed(0) + ' K';
      
        // MB
      if (size < Math.pow(unitSize, 3)) 
          return (size / Math.pow(unitSize, 2)).toFixed(2) + ' MB'
        
        // GB
      if (size < Math.pow(unitSize, 4)) 
          return (size / Math.pow(unitSize, 3)).toFixed(2) + ' GB';
      
           // TB
      return (size / Math.pow(unitSize, 4)).toFixed(2) + ' TB';        
      
    } 
     
  },
  filters: {
      transformByte(size) {
        if (!size) {
          return '0B'
        }
        const unitSize = 1024
        if (size < unitSize) {
          return size + ' B'
        }
        // KB
        if (size < Math.pow(unitSize, 2)) {
          return (size / unitSize).toFixed(2) + ' K';
        }
        // MB
        if (size < Math.pow(unitSize, 3)) {
          return (size / Math.pow(unitSize, 2)).toFixed(2) + ' MB'
        }
        // GB
        if (size < Math.pow(unitSize, 4)) {
          return (size / Math.pow(unitSize, 3)).toFixed(2) + ' GB';
        }
        // TB
        return (size / Math.pow(unitSize, 4)).toFixed(2) + ' TB';
      }
    }  
}
</script>

<style lang="scss">
  .queryForm {
    .el-form-item {
      margin-bottom: 10px;
    }
  }

  .upload-file-item {
  display: flex;
}
.file-progress {
  display: flex;
  align-items: center;
}
.file-progress-value {
  width: 250px;
}
.file-list-wrapper {
  margin-top: 20px;
}

.file-info-item {
  margin: 0 20px;
}

</style>
